package com.wyw.learning.thread.threadpool;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 几种关闭线程池相关知识点
 *  1、shutdown
 *  2、isShutdown
 *  3、isTerminated
 *  4、awaitTerminated
 *  5、shutdownNow
 *
 *  注意不同的任务最好采用不同线程池，用完即关闭，可以避免内存泄露的风险
 *  想停掉线程池中某个或者某几个线程，可以使用线程池中的remove方法，或者Future的cancel
 *
 * 线程池的拒绝策略
 *  1、拒绝时机
 *      1)、当Executor关闭时，提交新任务会被拒绝
 *      2)、当Executor对最大线程和工作队列容量使用边界并且已经饱和时
 *  2、四种拒绝策略
 *      AbortPolicy（抛异常）
 *      DiscardPolicy（默默的丢弃）
 *      DiscardOldestPolicy（丢弃最老的任务）
 *      CallerRunPolicy（谁提交的谁执行：这样可以不丢失，避免了业务损失；降低了提交者的提交速率）
 *
 * @author Mr Wu    yewen.wu.china@gmail.com
 * @date 2021/7/4   8:51 下午
 * <p>
 * Update History:
 * Author        Time            Content
 */
public class ShutDownThread {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for (int i = 0; i <100; i++){
            executorService.execute(new ShutDownTask());
        }
        try {
            Thread.sleep(1500);

            //立刻关闭，但是会需要执行完当前正在执行中的线程，队列中的线程会直接返回
            List<Runnable> runnables = executorService.shutdownNow();
            System.out.println("返回的集合：" + runnables);
            executorService.execute(new ShutDownTask());
//            executorService.shutdown();//不进行关闭的情况下，可以使用awaitTermination，检查他是否具有关闭线程池的操作
////            boolean b = executorService.awaitTermination(3L, TimeUnit.SECONDS);//等待3s，查看是否已经完全执行结束，这个操作不具备关闭线程池的操作
//            //等待时间到了，执行完毕，等待过程中被打断了，这三种情况会有返回值(达到了返回条件)
//            boolean b = executorService.awaitTermination(10L, TimeUnit.SECONDS);//等待3s，查看是否已经完全执行结束，这个操作不具备关闭线程池的操作
//            System.out.println(b);

//            //与shutdown相关联的isShutdown()，只要执行了shutdown方法，这个字段就是true
//            System.out.println("执行前" + executorService.isShutdown());
//            executorService.shutdown();//shutdown 是停止了新增，但是会处理完队列中的数据
//            System.out.println("执行后" + executorService.isShutdown());
//            //isTerminated()判断线程是否完全停止
//            System.out.println("是否完全停止" + executorService.isTerminated());
////            executorService.execute(new ShutDownTask());
//            Thread.sleep(10000);
//            System.out.println("是否完全停止" + executorService.isTerminated());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

//演示关闭的方法
class ShutDownTask implements Runnable{

    @Override
    public void run() {
        try {
            Thread.sleep(500);
            System.out.println(Thread.currentThread().getName());
        } catch (InterruptedException e) {
            System.out.println("线程被中断了" + Thread.currentThread().getName());

        }

    }
}
